import {
  CancelToken as CancelTokenInterface,
  CancelExecutor,
  Canceler,
  CancelTokenSource,
} from '../types'
import Cancel from './Cancel'

interface ResolvePromise {
  (reason?: Cancel): void
}

export default class CancelToken implements CancelTokenInterface {
  promise: Promise<Cancel>
  reason?: Cancel

  constructor(Executor: CancelExecutor) {
    let resolvePromise: ResolvePromise
    this.promise = new Promise<Cancel>((resolve) => {
      resolvePromise = resolve
    })
    // 看清楚，这里是执行函数Executor，并传入一个函数作为参数
    Executor((message) => {
      if (this.reason) {
        return
      }
      this.reason = new Cancel(message)
      resolvePromise(this.reason)
    })
  }
  static source(): CancelTokenSource {
    let cancel!: Canceler
    const token = new CancelToken((c) => {
      // 引用传递
      cancel = c
    })
    return {
      token,
      cancel,
    }
  }

  throwIfRequested() {
    // 因为
    if (this.reason) {
      throw this.reason
    }
  }
}
